﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using Steering.Robot;

namespace Steering.SteeringAbstraction
{
    /// <summary>
    /// This object is responsible for getting steering input
    /// an sendings commands to the robot.
    /// This is done periodically on a thread.
    /// </summary>
    public class ForkliftControl
    {
        private ForkliftSteeringSource steeringSource;
        private RobotControl robotControl;
        private int updatePause;

        private Thread steeringUpdater;

        private bool isRunning = true;
        private bool isActive = true;

        public ForkliftSteeringSource SteeringSource
        {
            get { return steeringSource; }
        }

        public bool IsActive
        {
            get { return isActive; }
            set { isActive = value; }
        }

        public ForkliftControl(ForkliftSteeringSource steeringSource, RobotControl robotControl, EventHandler stopIssued, EventHandler menuIssued)
        {
            this.steeringSource = steeringSource;
            this.robotControl = robotControl;
            this.updatePause = steeringSource.UpdatePause;

            this.steeringSource.StopIssued += stopIssued;
            this.steeringSource.MenuIssued += menuIssued;
        }

        public bool Start()
        {
            bool isConnected = this.robotControl.Connect();
            if (isConnected)
            {
                this.steeringUpdater = new Thread(new ThreadStart(this.UpdatingSteering));
                this.steeringSource.StartSteering();

                this.steeringUpdater.Start();
                this.isRunning = true;
            }
            return isConnected;        
        }

        public void Stop()
        {
            this.steeringSource.Halt();
            this.steeringSource.StopSteering();
            this.robotControl.Disconnect();
            this.isRunning = false;
        }

        public void Halt()
        {
            this.steeringSource.Halt();
        }

        /// <summary>
        /// Thread that updates steering values
        /// </summary>
        private void UpdatingSteering()
        {
            while (this.isRunning)
            {
                if (isActive)
                {
                    this.steeringSource.UpdateSteering();
                    UpdateRobot();
                }
                Thread.Sleep(updatePause);
            }
        }

        /// <summary>
        /// Sends appropriate commands to the robot.
        /// </summary>
        private void UpdateRobot()
        {
            this.robotControl.Move(this.steeringSource.Speed.Value, 0, this.steeringSource.Turn.Value);
            this.robotControl.ControlFork(this.steeringSource.ForkSpeed.Value);
        }
    }
}
